package splitframe.farm.rmiserver;

import java.io.IOException;
import java.io.OutputStream;
import java.util.logging.Logger;

import org.tiling.computefarm.impl.javaspaces.util.ClasspathServer;

import splitframe.farm.serviceutil.MulticastServiceUtil;

/**
 * A {@link SplitFrameClassPathServer} is a modified HTTP server for serving
 * class files from all jars found within a specified directory.
 */
public class SplitFrameClassPathServer extends ClasspathServer {

	private static final Logger logger = Logger
			.getLogger(SplitFrameClassPathServer.class.getName());

	private static JarServer jarServer = new JarServer();

	private static MulticastServiceUtil multicastServiceUtil;

	public SplitFrameClassPathServer(String jarDir) throws IOException {
		this(DEFAULT_START_PORT_NUMBER, jarDir);
	}

	public SplitFrameClassPathServer(int startPort, String jarDir)
			throws IOException {
		this(startPort, true, jarDir);
	}

	public SplitFrameClassPathServer(int startPort, boolean daemon,
			String jarDir) throws IOException {
		super(startPort, daemon);

		// start the jar indexing thread
		jarServer.setDirPaths(new String[] { jarDir });
		jarServer.setPriority(Thread.MIN_PRIORITY);
		jarServer.start();

		// start up the multicast server to broadcast this
		// http server's url as a codebase server
		multicastServiceUtil = new MulticastServiceUtil(true);
		multicastServiceUtil.start();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Thread#interrupt()
	 */
	public void interrupt() {
		// TODO Auto-generated method stub
		super.interrupt();
		try {
			multicastServiceUtil.stop();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			multicastServiceUtil = null;
			jarServer = null;
		}

	}

	protected void handleRequest(String method, String path, OutputStream out)
			throws IOException {
		if (method.equals("GET") || method.equals("HEAD")) {
			byte[] bytes = null;
			
			if(path.contains("/META-INF/services")) {
				path = path.substring("/META-INF/services".length()+1);
			}
			
			if (path.contains("PREFERRED.LIST")) {
				String list = "PreferredResources-Version: 1.0\r\nPreferred: false";
				bytes = list.getBytes();
			} else {
				bytes = jarServer.getBytes(path);
			}

			out.write("HTTP/1.0 200 OK\r\n".getBytes());
			out.write("Content-Type: application/java\r\n".getBytes());
			out.write(("Content-Length: " + bytes.length + "\r\n").getBytes());
			out.write("\r\n".getBytes());
			if (method.equals("GET")) {
				out.write(bytes);
			}
			out.flush();
			out.close();

		} else {
			sendError(out, "501", "Not Implemented");
			return;
		}

	}

	public static void main(String[] args) throws IOException {
		String dir = "c:/lib";
		int port = DEFAULT_START_PORT_NUMBER;
		if (args.length >= 1) {
			dir = args[0];
		}
		if (args.length >= 2) {
			port = new Integer(args[1]).intValue();
		}
		new SplitFrameClassPathServer(port, false, dir).start();
	}
}
